#include "BPEMatrix.h"

BPEMatrix::BPEMatrix() : 
	twoDimArray(boost::extents[1][1]){
	xSize=0;
	ySize=0;
	fill(0);
};

BPEMatrix::BPEMatrix(const int &x, const int &y): 
	twoDimArray(boost::extents[x][y]){
	xSize=x;
	ySize=y;
	fill(0);
};

void BPEMatrix::insertAt(const double &value, const int &x, const int &y){
	if( x > xSize ||  y > ySize )
		return;

	twoDimArray[x][y] = value;
	
};

double BPEMatrix::getFrom( const int &x, const int &y){
	if( x > xSize-1 ||  y > ySize-1 )
		return 0;
	
	return twoDimArray[x][y];
	
};


int BPEMatrix::getXSize(){return xSize;};
int BPEMatrix::getYSize(){return ySize;};


void BPEMatrix::fill(const double &num){
		for(int i=0; i<xSize; i++)
		for(int j=0; j<ySize; j++)
			twoDimArray[i][j] =num;
	
};
BPEMatrix BPEMatrix::add(const BPEMatrix &tempMatrix){

	if(this->getXSize() != tempMatrix.xSize || this->getYSize() != tempMatrix.ySize)
		return BPEMatrix();


	BPEMatrix result(xSize,ySize);
	for(int i=0; i<xSize; i++)
		for(int j=0; j<ySize; j++)
			result.insertAt( this->twoDimArray[i][j] + tempMatrix.twoDimArray[i][j],i,j);

	return result;
	
};

BPEMatrix BPEMatrix::multiply(BPEMatrix tempMatrix){
	int r1 = this->getXSize();
	int c1 = this->getYSize();
	int r2 = tempMatrix.getXSize();
	int c2 = tempMatrix.getYSize();

	//dont ask how :P
	if(c1 == r2){
		BPEMatrix result(r1,c2);
		
		for(int i = 0; i < r1; i++){

			for(int j = 0; j < c2; j++){

				for(int k = 0; k < r2 ;k++){

					double temp = result.getFrom(i,j);
					double firstMatrix = this->getFrom(i,k);
					double secondMatrix = tempMatrix.getFrom(k,j);
					double inserted = temp + firstMatrix*secondMatrix;
					result.insertAt(inserted,i,j);

				}
			}
		}
		return result;
	}
	return BPEMatrix();
	
};

